﻿using System;
using System.Collections.Generic;
using System.Data;
using Ue.Infrastructure.DomainBase;
using Ue.Infrastructure.RepositoryFramework.Repository;
using Ue.Qcdz.Domain;
using Ue.Qcdz.Domain.Membership;
using Ue.Qcdz.Domain.Roles;
using Ue.Qcdz.Domain.SaleInfos;
using Ue.Qcdz.Domain.Shops;
using Ue.Qcdz.UI.Controls.SaleInfo;

namespace Ue.Qcdz.Repositories.SaleInfos
{
    public class SaleInfoRepository : SqlServerRepository<SaleInfo>, ISaleInfoRepository
    {
        #region Overrides of SqlServerRepositoryBase<SaleInfo>

        protected override string GetDataTableName()
        {
            return "SaleInfo";
        }
        protected override string GetKeyFieldName()
        {
            return SaleInfoFactory.FieldNames.EntityKey;
        }
        protected override string[] GetBaseInsertFields()
        {
            return new string[]
                       {
                           SaleInfoFactory.FieldNames.EntityKey,
                           SaleInfoFactory.FieldNames.UserId,
                           SaleInfoFactory.FieldNames.SalesType,
                           SaleInfoFactory.FieldNames.SalteTitle,
                           SaleInfoFactory.FieldNames.Brand,
                           SaleInfoFactory.FieldNames.Description,
                           SaleInfoFactory.FieldNames.Directory,
                           SaleInfoFactory.FieldNames.KeyWord,
                           SaleInfoFactory.FieldNames.Model,
                           SaleInfoFactory.FieldNames.Period,
                           SaleInfoFactory.FieldNames.PicUrl,
                           SaleInfoFactory.FieldNames.ShopId,
                           SaleInfoFactory.FieldNames.SaleCategoryId,
                           SaleInfoFactory.FieldNames.Deadline
                          
        };
        }

        protected override string[] GetBaseUpdateFields()
        {
            return new string[]
                       {
                           SaleInfoFactory.FieldNames.UserId,
                           SaleInfoFactory.FieldNames.SalesType,
                           SaleInfoFactory.FieldNames.SalteTitle,
                           SaleInfoFactory.FieldNames.Brand,
                           SaleInfoFactory.FieldNames.Description,
                           SaleInfoFactory.FieldNames.Directory,
                           SaleInfoFactory.FieldNames.KeyWord,
                           SaleInfoFactory.FieldNames.Model,
                           SaleInfoFactory.FieldNames.Period,
                           SaleInfoFactory.FieldNames.PicUrl,
                           SaleInfoFactory.FieldNames.IsTop,
                           SaleInfoFactory.FieldNames.IsHot,
                           SaleInfoFactory.FieldNames.ShopId,
                           SaleInfoFactory.FieldNames.SaleCategoryId,
                           SaleInfoFactory.FieldNames.Deadline
                          
        };
        }

        protected override IDataParameter[] BuildParameters(SaleInfo entity)
        {
            return new IDataParameter[]
                       {
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.EntityKey,entity.Key),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.UserId,entity.UserId),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Brand,entity.Brand),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Description,entity.Description),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Directory,entity.Directory), 
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.KeyWord,entity.KeyWord), 
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Model,entity.Model), 
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Period,entity.Period), 
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.PicUrl,entity.PicUrl), 
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SalesType,entity.SalesType), 
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SalteTitle,entity.SalteTitle),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.IsTop,entity.IsTop),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.IsHot,entity.IsHot),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.ShopId,entity.ShopId),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SaleCategoryId,entity.SaleCategoryId),
                            this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Deadline,entity.Deadline)

                       };
        }

        protected override IWhereClause BuildWhereClauseBy(IDataQuery dataQuery)
        {
            if (dataQuery is SaleInfoGirdView)
            {
                SaleInfoGirdView saleInfoGirdView = dataQuery as SaleInfoGirdView;
                return new SaleWhereClause(saleInfoGirdView);

            }
            else if (dataQuery is SaleInfoSearchList)
            {
                SaleInfoSearchList saleInfoSearchList = dataQuery as SaleInfoSearchList;
                return new SearchListClause(saleInfoSearchList);

            }

            return null;
        }

        protected override IDictionary<string, ChildDataHandler> GetBuildEntityChildCallbacks()
        {
            var callBacks = new Dictionary<string, SqlServerRepository<SaleInfo>.ChildDataHandler>();
            callBacks.Add(SaleInfoFactory.FieldNames.EntityKey, delegate(SaleInfo saleInfo, object objectValue)
            {
                IShopRepository shopRepository = Ue.Infrastructure.RepositoryFramework.RepositoryFactory.GetRepository<IShopRepository, Shop>();

                saleInfo.shop = ShopService.GetShop(new Guid(saleInfo.ShopId));


            });

            return callBacks;
        }

        public class SearchListClause : IWhereClause
        {
            #region Implementation of IWhereClause

            public SaleInfoSearchList saleInfoSearchList;
            public SearchListClause(SaleInfoSearchList saleInfoSearchList)
            {
                this.saleInfoSearchList = saleInfoSearchList;
            }

            public string Clause
            {
                get
                {
                    var clause =
                        "SalesType LIKE '%'+@SalesType+'%' AND(SalteTitle LIKE '%'+@SalteTitle+'%' OR KeyWord LIKE '%'+@KeyWord+'%' OR Description LIKE '%'+@Description+'%')";
                    return clause;
                }
            }

            public IDataParameter[] Parameters
            {
                get
                {
                    if (string.IsNullOrEmpty(saleInfoSearchList.SalesType)) saleInfoSearchList.SalesType = "";
                    if (string.IsNullOrEmpty(saleInfoSearchList.SearchKey)) saleInfoSearchList.SearchKey = "";
                    var Parameters = new IDataParameter[]
                                         {
                                            SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.SalesType,
                                                                                     saleInfoSearchList.SalesType),
                                            SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.SalteTitle,
                                                                                     saleInfoSearchList.SearchKey),
                                            SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.KeyWord,
                                                                                     saleInfoSearchList.SearchKey),
                                            SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.Description,
                                                                                     saleInfoSearchList.SearchKey)

                                         };
                    return Parameters;
                }
            }

            #endregion
        }
        #endregion
        public class SaleWhereClause : IWhereClause
        {
            #region Implementation of IWhereClause

            public SaleInfoGirdView saleInfoGirdView;
            public SaleWhereClause(SaleInfoGirdView saleInfoGirdView)
            {
                this.saleInfoGirdView = saleInfoGirdView;
            }

            public string Clause
            {
                get
                {
                    var clause =
                        "SalteTitle LIKE '%'+@SalteTitle+'%' AND KeyWord LIKE '%'+@KeyWord+'%' AND SalesType LIKE '%'+@SalesType+'%' AND IsTop LIKE '%'+@IsTop+'%' AND IsHot LIKE '%'+@IsHot+'%'";
                    return clause;
                }
            }

            public IDataParameter[] Parameters
            {
                get
                {
                    if (string.IsNullOrEmpty(saleInfoGirdView.Title)) saleInfoGirdView.Title = "";
                    if (string.IsNullOrEmpty(saleInfoGirdView.KeyWord)) saleInfoGirdView.KeyWord = "";
                    if (string.IsNullOrEmpty(saleInfoGirdView.Type)) saleInfoGirdView.Type = "";
                    if (string.IsNullOrEmpty(saleInfoGirdView.IsTop)) saleInfoGirdView.IsTop = "";
                    if (string.IsNullOrEmpty(saleInfoGirdView.IsHot)) saleInfoGirdView.IsHot = "";
                    var Parameters = new IDataParameter[]
                                         {
                                             SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.SalteTitle,
                                                                                     saleInfoGirdView.Title),
                                             SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.KeyWord,
                                                                                     saleInfoGirdView.KeyWord),
                                             SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.SalesType,
                                                                                     saleInfoGirdView.Type),
                                             SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.IsTop,
                                                                                     saleInfoGirdView.IsTop),
                                             SqlServerDriver.Instance.BuildParameter(SaleInfoFactory.FieldNames.IsHot,
                                                                                     saleInfoGirdView.IsHot)
                                         };
                    return Parameters;
                }
            }

            #endregion
        }

        #region Implementation of ISaleInfoRepository

        public IList<SaleInfo> GetTop(int num)
        {
            var query = string.Format("SELECT TOP {0} * FROM SaleInfo WHERE IsTop=1 AND  Deadline> GETDATE()", num);
            return this.BuildEntitiesFromSql(query);
        }

        public IList<SaleInfo> FindBy(string keyWord, SaleInfoEnum saleType)
        {
            var query =
                "SELECT * FROM SaleInfo WHERE SalesType=@SalesType OR SalteTitle LIKE '%'+@SalteTitle+'%' OR KeyWord LIKE '%'+@KeyWord+'%' OR Description LIKE '%'+@Description+'%'  AND  Deadline> GETDATE()";
            var parameter = new IDataParameter[]
                                {
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SalesType, saleType)
                                    ,
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SalteTitle, keyWord)
                                    ,
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.KeyWord, keyWord)
                                    ,
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.Description, keyWord)

                                };
            return this.BuildEntitiesFromSql(query, parameter);
        }

        public IList<SaleInfo> FindBy(string userId, string shopId)
        {
            var query = "SELECT SaleInfo.*,Shop.Remark FROM  SaleInfo INNER JOIN [Shop] ON SaleInfo.shopId=[Shop].Id WHERE SaleInfo.userId=@userId AND shopId=@shopId  AND  Deadline> GETDATE()";
            var parameter = new IDataParameter[]
                                {
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.UserId, userId),
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.ShopId,shopId)
                                };
            return this.BuildEntitiesFromSql(query, parameter);
        }

        public IList<SaleInfo> FindBy(string shopId)
        {
            var query = "SELECT * FROM SaleInfo WHERE shopId=@shopId  AND  Deadline> GETDATE()";
            var parameter = new IDataParameter[]
                                {
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.ShopId,shopId)
                                };
            return this.BuildEntitiesFromSql(query, parameter);
        }

        public IList<SaleInfo> FindBy(int num, SaleInfoEnum saleType)
        {
            var query = string.Format("SELECT TOP {0} * FROM SaleInfo WHERE IsTop=1 AND SalesType=@SalesType AND  Deadline> GETDATE()", num);
            var parameter = new IDataParameter[]
                                {
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SalesType, saleType)
                                };
            return this.BuildEntitiesFromSql(query, parameter);

        }

        public int GetCount(User user)
        {
            var query = "SELECT COUNT (*) FROM SaleInfo WHERE userId=@userId AND  Deadline> GETDATE()";
            var parameter = new IDataParameter[]
                                {
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.UserId, user.Key)
                                };
            return this.ExecuteReader(query, parameter).FieldCount;
        }

        #endregion

        #region ISaleInfoRepository 成员

        /// <summary>
        /// Juju
        /// </summary>
        /// <param name="shop"></param>
        public void RemoveAll(Shop shop)
        {
            if (shop == null) return;
            var query = "DELETE FROM SaleInfo WHERE ShopId=@ShopId AND  Deadline> GETDATE()";
            var parameter = new IDataParameter[]
                                {
                                    this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.ShopId,shop.Key),
                             
                                };
            this.BuildEntitiesFromSql(query, parameter);
        }

        #endregion

        #region ISaleInfoRepository 成员


        public IList<SaleInfo> FindBy(Domain.SaleCategorys.SaleCategory category)
        {
            if (category == null) 
                return null;

            var query = "SELECT * FROM SaleInfo WHERE SaleCategoryId=@SaleCategoryId  AND  Deadline> GETDATE()";

            return this.BuildEntitiesFromSql(query, this.RepositoryDriver.BuildParameter(SaleInfoFactory.FieldNames.SaleCategoryId, category.Key));
        }

        #endregion
    }
}
